﻿namespace Blaze.UI
{
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;

    /// <summary>
    /// 适用于低性能设备的<see cref="Image"/>替代方案，舍弃模版检测和混合特性来提高性能。
    /// </summary>
    public class FastImage : Image
    {

        protected FastImage()
        {
            useLegacyMeshGeneration = false;
        }
        /// <summary>
        /// <para>
        /// Returns the default material for the graphic.
        /// </para>
        /// </summary>
        public override Material defaultMaterial
        {
            get
            {
                if (ActiveSprite == null)
                {
                    return UIMaterialUtility.FastStand;
                } 

                if (IsAlphaSplitEnabled)
                {
                    if (IsMaskEnabled)
                    {
                        if (IsAutoETC1Enabled)
                            return UIMaterialUtility.Stand_AplhaSplit_AutoETC1;
                        else
                            return UIMaterialUtility.Stand_AlphaSplit;
                    }
                    else
                    {
                        if (IsAutoETC1Enabled)
                            return UIMaterialUtility.FastStand_AlphaSplit_AutoETC1;
                        else
                            return UIMaterialUtility.FastStand_AlphaSplit;
                    }
                }
                else
                {
                    if (IsMaskEnabled)
                    {
                        return UIMaterialUtility.Stand;
                    }
                    else
                    {
                        return UIMaterialUtility.FastStand;
                    }
                }

                return UIMaterialUtility.Stand;
            }
        }

        public override Material material
        {
            get
            {
                if (m_Material != null)
                {
#if UNITY_EDITOR_OSX || UNITY_IOS
                    m_Material.EnableKeyword("BLAZE_UI_ALPHASPLIT");
                    m_Material.DisableKeyword("BLAZE_UI_ETC1COMPRESS");
#endif
                    return m_Material;
                }

#if UNITY_EDITOR
                if (Application.isPlaying == false)
                {
                    return UIMaterialUtility.Stand;
                }

                return defaultMaterial;
#endif

                return defaultMaterial;
            }

            set { base.material = value; }
        }

        /// <summary>
        /// 是否使用Alpha分离方式
        /// </summary>
        public bool IsAlphaSplitEnabled
        {
            get
            {
#if UNITY_EDITOR_OSX || UNITY_IOS
                return false;
#endif
                return mIsAlphaSplitEnabled;
            }
            set
            {
                if (mIsAlphaSplitEnabled == value)
                    return;

                mIsAlphaSplitEnabled = value;
                SetAllDirty();
            }
        }

        /// <summary>
        /// 是否使用Unity自动分离Alpha
        /// </summary>
        public bool IsAutoETC1Enabled
        {
            get { return mIsAutoETC1Enabled; }

            set
            {
                if (mIsAutoETC1Enabled == value)
                    return;

                mIsAutoETC1Enabled = value;
                SetAllDirty();
            }
        }

        /// <summary>
        /// 是否开启Mask功能。
        /// </summary>
        public bool IsMaskEnabled
        {
            get { return mIsMaskEnabled; }
            set
            {
                if (mIsMaskEnabled == value)
                    return;

                mIsMaskEnabled = value;
                SetAllDirty();
            }
        }

        /// <summary>
        /// 是否开启PolygonImage网格填充方式。
        /// 目前只支持simple图片
        /// </summary>
        public bool IsPolygonEnabled
        {
            get { return mIsPolygonEnabled; }
            set
            {
                if (mIsPolygonEnabled == value)
                    return;

                mIsPolygonEnabled = value;
                SetAllDirty();
            }
        }

        protected Sprite ActiveSprite
        {
            get
            {
                if (overrideSprite == null)
                    return sprite;
                return overrideSprite;
            }
        }

        protected override void UpdateMaterial()
        {
            base.UpdateMaterial();
        }

        protected override void OnPopulateMesh(VertexHelper toFill)
        {
            if (color.a == 0f)
            {
                toFill.Clear();
                return;
            }

            if (overrideSprite == null)
            {
                base.OnPopulateMesh(toFill);
                return;
            }

            if (!mIsPolygonEnabled)
            {
                base.OnPopulateMesh(toFill);
                return;
            }

            switch (type)
            {
                case Type.Simple:
                    GenerateSimpleSprite(toFill);
                    break;
                case Type.Sliced:
                case Type.Tiled:
                case Type.Filled:
                    base.OnPopulateMesh(toFill);
                    break;
            }

        }

#region 填充mesh数据
        /// <summary>
        /// 生成Simple的mesh信息
        /// </summary>
        /// <param name="vh"></param>
        private void GenerateSimpleSprite(VertexHelper vh)
        {
            rectTransform.GetLocalCorners(fourCorners);

            int len = overrideSprite.vertices.Length;
            var vertices = new List<UIVertex>(len);
            Vector2 Center = overrideSprite.bounds.center;
            Vector2 invExtend = new Vector2(1 / overrideSprite.bounds.size.x, 1 / overrideSprite.bounds.size.y);
            for (int i = 0; i < len; i++)
            {
                // normalize
                float x = (overrideSprite.vertices[i].x - Center.x) * invExtend.x + 0.5f;
                float y = (overrideSprite.vertices[i].y - Center.y) * invExtend.y + 0.5f;
                // lerp to position
                vertice.position = new Vector2(Mathf.Lerp(fourCorners[0].x, fourCorners[2].x, x), Mathf.Lerp(fourCorners[0].y, fourCorners[2].y, y));
                vertice.color = color;
                vertice.uv0 = overrideSprite.uv[i];
                vertices.Add(vertice);
            }

            len = overrideSprite.triangles.Length;
            var triangles = new List<int>(len);
            for (int i = 0; i < len; i++)
            {
                triangles.Add(overrideSprite.triangles[i]);
            }

            vh.Clear();
            vh.AddUIVertexStream(vertices, triangles);
        }
#endregion

        [SerializeField] private bool mIsAlphaSplitEnabled = true;
        [SerializeField] private bool mIsAutoETC1Enabled = true;
        [SerializeField] private bool mIsPolygonEnabled = true;
        [SerializeField] private bool mIsMaskEnabled = false;

        private static Vector3[] fourCorners = new Vector3[4];
        private static UIVertex vertice = new UIVertex();
    }
}